/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package Dao;

import Dao.exceptions.IllegalOrphanException;
import Dao.exceptions.NonexistentEntityException;
import Dao.exceptions.PreexistingEntityException;
import java.io.Serializable;
import javax.persistence.Query;
import javax.persistence.EntityNotFoundException;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Root;
import Logico.Competencia;
import java.util.ArrayList;
import java.util.List;
import Logico.Evento;
import Logico.Usuario;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;

/**
 *
 * @author usuario
 */
public class UsuarioJpaController implements Serializable {

    public UsuarioJpaController(EntityManagerFactory emf) {
        this.emf = emf;
    }
    private EntityManagerFactory emf = null;

    public EntityManager getEntityManager() {
        return emf.createEntityManager();
    }

    public void create(Usuario usuario) throws PreexistingEntityException, Exception {
        if (usuario.getCompetenciaList() == null) {
            usuario.setCompetenciaList(new ArrayList<Competencia>());
        }
        if (usuario.getCompetenciaList1() == null) {
            usuario.setCompetenciaList1(new ArrayList<Competencia>());
        }
        if (usuario.getEventoList() == null) {
            usuario.setEventoList(new ArrayList<Evento>());
        }
        if (usuario.getEventoList1() == null) {
            usuario.setEventoList1(new ArrayList<Evento>());
        }
        if (usuario.getEventoList2() == null) {
            usuario.setEventoList2(new ArrayList<Evento>());
        }
        if (usuario.getEventoList3() == null) {
            usuario.setEventoList3(new ArrayList<Evento>());
        }
        EntityManager em = null;
        try {
            em = getEntityManager();
            em.getTransaction().begin();
            List<Competencia> attachedCompetenciaList = new ArrayList<Competencia>();
            for (Competencia competenciaListCompetenciaToAttach : usuario.getCompetenciaList()) {
                competenciaListCompetenciaToAttach = em.getReference(competenciaListCompetenciaToAttach.getClass(), competenciaListCompetenciaToAttach.getIdcompetencia());
                attachedCompetenciaList.add(competenciaListCompetenciaToAttach);
            }
            usuario.setCompetenciaList(attachedCompetenciaList);
            List<Competencia> attachedCompetenciaList1 = new ArrayList<Competencia>();
            for (Competencia competenciaList1CompetenciaToAttach : usuario.getCompetenciaList1()) {
                competenciaList1CompetenciaToAttach = em.getReference(competenciaList1CompetenciaToAttach.getClass(), competenciaList1CompetenciaToAttach.getIdcompetencia());
                attachedCompetenciaList1.add(competenciaList1CompetenciaToAttach);
            }
            usuario.setCompetenciaList1(attachedCompetenciaList1);
            List<Evento> attachedEventoList = new ArrayList<Evento>();
            for (Evento eventoListEventoToAttach : usuario.getEventoList()) {
                eventoListEventoToAttach = em.getReference(eventoListEventoToAttach.getClass(), eventoListEventoToAttach.getIdevento());
                attachedEventoList.add(eventoListEventoToAttach);
            }
            usuario.setEventoList(attachedEventoList);
            List<Evento> attachedEventoList1 = new ArrayList<Evento>();
            for (Evento eventoList1EventoToAttach : usuario.getEventoList1()) {
                eventoList1EventoToAttach = em.getReference(eventoList1EventoToAttach.getClass(), eventoList1EventoToAttach.getIdevento());
                attachedEventoList1.add(eventoList1EventoToAttach);
            }
            usuario.setEventoList1(attachedEventoList1);
            List<Evento> attachedEventoList2 = new ArrayList<Evento>();
            for (Evento eventoList2EventoToAttach : usuario.getEventoList2()) {
                eventoList2EventoToAttach = em.getReference(eventoList2EventoToAttach.getClass(), eventoList2EventoToAttach.getIdevento());
                attachedEventoList2.add(eventoList2EventoToAttach);
            }
            usuario.setEventoList2(attachedEventoList2);
            List<Evento> attachedEventoList3 = new ArrayList<Evento>();
            for (Evento eventoList3EventoToAttach : usuario.getEventoList3()) {
                eventoList3EventoToAttach = em.getReference(eventoList3EventoToAttach.getClass(), eventoList3EventoToAttach.getIdevento());
                attachedEventoList3.add(eventoList3EventoToAttach);
            }
            usuario.setEventoList3(attachedEventoList3);
            em.persist(usuario);
            for (Competencia competenciaListCompetencia : usuario.getCompetenciaList()) {
                competenciaListCompetencia.getUsuarioList().add(usuario);
                competenciaListCompetencia = em.merge(competenciaListCompetencia);
            }
            for (Competencia competenciaList1Competencia : usuario.getCompetenciaList1()) {
                competenciaList1Competencia.getUsuarioList1().add(usuario);
                competenciaList1Competencia = em.merge(competenciaList1Competencia);
            }
            for (Evento eventoListEvento : usuario.getEventoList()) {
                Usuario oldCeduladirectorlogisticaOfEventoListEvento = eventoListEvento.getCeduladirectorlogistica();
                eventoListEvento.setCeduladirectorlogistica(usuario);
                eventoListEvento = em.merge(eventoListEvento);
                if (oldCeduladirectorlogisticaOfEventoListEvento != null) {
                    oldCeduladirectorlogisticaOfEventoListEvento.getEventoList().remove(eventoListEvento);
                    oldCeduladirectorlogisticaOfEventoListEvento = em.merge(oldCeduladirectorlogisticaOfEventoListEvento);
                }
            }
            for (Evento eventoList1Evento : usuario.getEventoList1()) {
                Usuario oldCeduladirectoradministrativoOfEventoList1Evento = eventoList1Evento.getCeduladirectoradministrativo();
                eventoList1Evento.setCeduladirectoradministrativo(usuario);
                eventoList1Evento = em.merge(eventoList1Evento);
                if (oldCeduladirectoradministrativoOfEventoList1Evento != null) {
                    oldCeduladirectoradministrativoOfEventoList1Evento.getEventoList1().remove(eventoList1Evento);
                    oldCeduladirectoradministrativoOfEventoList1Evento = em.merge(oldCeduladirectoradministrativoOfEventoList1Evento);
                }
            }
            for (Evento eventoList2Evento : usuario.getEventoList2()) {
                Usuario oldCeduladirectordeportivoOfEventoList2Evento = eventoList2Evento.getCeduladirectordeportivo();
                eventoList2Evento.setCeduladirectordeportivo(usuario);
                eventoList2Evento = em.merge(eventoList2Evento);
                if (oldCeduladirectordeportivoOfEventoList2Evento != null) {
                    oldCeduladirectordeportivoOfEventoList2Evento.getEventoList2().remove(eventoList2Evento);
                    oldCeduladirectordeportivoOfEventoList2Evento = em.merge(oldCeduladirectordeportivoOfEventoList2Evento);
                }
            }
            for (Evento eventoList3Evento : usuario.getEventoList3()) {
                Usuario oldCeduladirectoreventoOfEventoList3Evento = eventoList3Evento.getCeduladirectorevento();
                eventoList3Evento.setCeduladirectorevento(usuario);
                eventoList3Evento = em.merge(eventoList3Evento);
                if (oldCeduladirectoreventoOfEventoList3Evento != null) {
                    oldCeduladirectoreventoOfEventoList3Evento.getEventoList3().remove(eventoList3Evento);
                    oldCeduladirectoreventoOfEventoList3Evento = em.merge(oldCeduladirectoreventoOfEventoList3Evento);
                }
            }
            em.getTransaction().commit();
        } catch (Exception ex) {
            if (findUsuario(usuario.getCedula()) != null) {
                throw new PreexistingEntityException("Usuario " + usuario + " already exists.", ex);
            }
            throw ex;
        } finally {
            if (em != null) {
                em.close();
            }
        }
    }

    public void edit(Usuario usuario) throws IllegalOrphanException, NonexistentEntityException, Exception {
        EntityManager em = null;
        try {
            em = getEntityManager();
            em.getTransaction().begin();
            Usuario persistentUsuario = em.find(Usuario.class, usuario.getCedula());
            List<Competencia> competenciaListOld = persistentUsuario.getCompetenciaList();
            List<Competencia> competenciaListNew = usuario.getCompetenciaList();
            List<Competencia> competenciaList1Old = persistentUsuario.getCompetenciaList1();
            List<Competencia> competenciaList1New = usuario.getCompetenciaList1();
            List<Evento> eventoListOld = persistentUsuario.getEventoList();
            List<Evento> eventoListNew = usuario.getEventoList();
            List<Evento> eventoList1Old = persistentUsuario.getEventoList1();
            List<Evento> eventoList1New = usuario.getEventoList1();
            List<Evento> eventoList2Old = persistentUsuario.getEventoList2();
            List<Evento> eventoList2New = usuario.getEventoList2();
            List<Evento> eventoList3Old = persistentUsuario.getEventoList3();
            List<Evento> eventoList3New = usuario.getEventoList3();
            List<String> illegalOrphanMessages = null;
            for (Evento eventoList3OldEvento : eventoList3Old) {
                if (!eventoList3New.contains(eventoList3OldEvento)) {
                    if (illegalOrphanMessages == null) {
                        illegalOrphanMessages = new ArrayList<String>();
                    }
                    illegalOrphanMessages.add("You must retain Evento " + eventoList3OldEvento + " since its ceduladirectorevento field is not nullable.");
                }
            }
            if (illegalOrphanMessages != null) {
                throw new IllegalOrphanException(illegalOrphanMessages);
            }
            List<Competencia> attachedCompetenciaListNew = new ArrayList<Competencia>();
            for (Competencia competenciaListNewCompetenciaToAttach : competenciaListNew) {
                competenciaListNewCompetenciaToAttach = em.getReference(competenciaListNewCompetenciaToAttach.getClass(), competenciaListNewCompetenciaToAttach.getIdcompetencia());
                attachedCompetenciaListNew.add(competenciaListNewCompetenciaToAttach);
            }
            competenciaListNew = attachedCompetenciaListNew;
            usuario.setCompetenciaList(competenciaListNew);
            List<Competencia> attachedCompetenciaList1New = new ArrayList<Competencia>();
            for (Competencia competenciaList1NewCompetenciaToAttach : competenciaList1New) {
                competenciaList1NewCompetenciaToAttach = em.getReference(competenciaList1NewCompetenciaToAttach.getClass(), competenciaList1NewCompetenciaToAttach.getIdcompetencia());
                attachedCompetenciaList1New.add(competenciaList1NewCompetenciaToAttach);
            }
            competenciaList1New = attachedCompetenciaList1New;
            usuario.setCompetenciaList1(competenciaList1New);
            List<Evento> attachedEventoListNew = new ArrayList<Evento>();
            for (Evento eventoListNewEventoToAttach : eventoListNew) {
                eventoListNewEventoToAttach = em.getReference(eventoListNewEventoToAttach.getClass(), eventoListNewEventoToAttach.getIdevento());
                attachedEventoListNew.add(eventoListNewEventoToAttach);
            }
            eventoListNew = attachedEventoListNew;
            usuario.setEventoList(eventoListNew);
            List<Evento> attachedEventoList1New = new ArrayList<Evento>();
            for (Evento eventoList1NewEventoToAttach : eventoList1New) {
                eventoList1NewEventoToAttach = em.getReference(eventoList1NewEventoToAttach.getClass(), eventoList1NewEventoToAttach.getIdevento());
                attachedEventoList1New.add(eventoList1NewEventoToAttach);
            }
            eventoList1New = attachedEventoList1New;
            usuario.setEventoList1(eventoList1New);
            List<Evento> attachedEventoList2New = new ArrayList<Evento>();
            for (Evento eventoList2NewEventoToAttach : eventoList2New) {
                eventoList2NewEventoToAttach = em.getReference(eventoList2NewEventoToAttach.getClass(), eventoList2NewEventoToAttach.getIdevento());
                attachedEventoList2New.add(eventoList2NewEventoToAttach);
            }
            eventoList2New = attachedEventoList2New;
            usuario.setEventoList2(eventoList2New);
            List<Evento> attachedEventoList3New = new ArrayList<Evento>();
            for (Evento eventoList3NewEventoToAttach : eventoList3New) {
                eventoList3NewEventoToAttach = em.getReference(eventoList3NewEventoToAttach.getClass(), eventoList3NewEventoToAttach.getIdevento());
                attachedEventoList3New.add(eventoList3NewEventoToAttach);
            }
            eventoList3New = attachedEventoList3New;
            usuario.setEventoList3(eventoList3New);
            usuario = em.merge(usuario);
            for (Competencia competenciaListOldCompetencia : competenciaListOld) {
                if (!competenciaListNew.contains(competenciaListOldCompetencia)) {
                    competenciaListOldCompetencia.getUsuarioList().remove(usuario);
                    competenciaListOldCompetencia = em.merge(competenciaListOldCompetencia);
                }
            }
            for (Competencia competenciaListNewCompetencia : competenciaListNew) {
                if (!competenciaListOld.contains(competenciaListNewCompetencia)) {
                    competenciaListNewCompetencia.getUsuarioList().add(usuario);
                    competenciaListNewCompetencia = em.merge(competenciaListNewCompetencia);
                }
            }
            for (Competencia competenciaList1OldCompetencia : competenciaList1Old) {
                if (!competenciaList1New.contains(competenciaList1OldCompetencia)) {
                    competenciaList1OldCompetencia.getUsuarioList1().remove(usuario);
                    competenciaList1OldCompetencia = em.merge(competenciaList1OldCompetencia);
                }
            }
            for (Competencia competenciaList1NewCompetencia : competenciaList1New) {
                if (!competenciaList1Old.contains(competenciaList1NewCompetencia)) {
                    competenciaList1NewCompetencia.getUsuarioList1().add(usuario);
                    competenciaList1NewCompetencia = em.merge(competenciaList1NewCompetencia);
                }
            }
            for (Evento eventoListOldEvento : eventoListOld) {
                if (!eventoListNew.contains(eventoListOldEvento)) {
                    eventoListOldEvento.setCeduladirectorlogistica(null);
                    eventoListOldEvento = em.merge(eventoListOldEvento);
                }
            }
            for (Evento eventoListNewEvento : eventoListNew) {
                if (!eventoListOld.contains(eventoListNewEvento)) {
                    Usuario oldCeduladirectorlogisticaOfEventoListNewEvento = eventoListNewEvento.getCeduladirectorlogistica();
                    eventoListNewEvento.setCeduladirectorlogistica(usuario);
                    eventoListNewEvento = em.merge(eventoListNewEvento);
                    if (oldCeduladirectorlogisticaOfEventoListNewEvento != null && !oldCeduladirectorlogisticaOfEventoListNewEvento.equals(usuario)) {
                        oldCeduladirectorlogisticaOfEventoListNewEvento.getEventoList().remove(eventoListNewEvento);
                        oldCeduladirectorlogisticaOfEventoListNewEvento = em.merge(oldCeduladirectorlogisticaOfEventoListNewEvento);
                    }
                }
            }
            for (Evento eventoList1OldEvento : eventoList1Old) {
                if (!eventoList1New.contains(eventoList1OldEvento)) {
                    eventoList1OldEvento.setCeduladirectoradministrativo(null);
                    eventoList1OldEvento = em.merge(eventoList1OldEvento);
                }
            }
            for (Evento eventoList1NewEvento : eventoList1New) {
                if (!eventoList1Old.contains(eventoList1NewEvento)) {
                    Usuario oldCeduladirectoradministrativoOfEventoList1NewEvento = eventoList1NewEvento.getCeduladirectoradministrativo();
                    eventoList1NewEvento.setCeduladirectoradministrativo(usuario);
                    eventoList1NewEvento = em.merge(eventoList1NewEvento);
                    if (oldCeduladirectoradministrativoOfEventoList1NewEvento != null && !oldCeduladirectoradministrativoOfEventoList1NewEvento.equals(usuario)) {
                        oldCeduladirectoradministrativoOfEventoList1NewEvento.getEventoList1().remove(eventoList1NewEvento);
                        oldCeduladirectoradministrativoOfEventoList1NewEvento = em.merge(oldCeduladirectoradministrativoOfEventoList1NewEvento);
                    }
                }
            }
            for (Evento eventoList2OldEvento : eventoList2Old) {
                if (!eventoList2New.contains(eventoList2OldEvento)) {
                    eventoList2OldEvento.setCeduladirectordeportivo(null);
                    eventoList2OldEvento = em.merge(eventoList2OldEvento);
                }
            }
            for (Evento eventoList2NewEvento : eventoList2New) {
                if (!eventoList2Old.contains(eventoList2NewEvento)) {
                    Usuario oldCeduladirectordeportivoOfEventoList2NewEvento = eventoList2NewEvento.getCeduladirectordeportivo();
                    eventoList2NewEvento.setCeduladirectordeportivo(usuario);
                    eventoList2NewEvento = em.merge(eventoList2NewEvento);
                    if (oldCeduladirectordeportivoOfEventoList2NewEvento != null && !oldCeduladirectordeportivoOfEventoList2NewEvento.equals(usuario)) {
                        oldCeduladirectordeportivoOfEventoList2NewEvento.getEventoList2().remove(eventoList2NewEvento);
                        oldCeduladirectordeportivoOfEventoList2NewEvento = em.merge(oldCeduladirectordeportivoOfEventoList2NewEvento);
                    }
                }
            }
            for (Evento eventoList3NewEvento : eventoList3New) {
                if (!eventoList3Old.contains(eventoList3NewEvento)) {
                    Usuario oldCeduladirectoreventoOfEventoList3NewEvento = eventoList3NewEvento.getCeduladirectorevento();
                    eventoList3NewEvento.setCeduladirectorevento(usuario);
                    eventoList3NewEvento = em.merge(eventoList3NewEvento);
                    if (oldCeduladirectoreventoOfEventoList3NewEvento != null && !oldCeduladirectoreventoOfEventoList3NewEvento.equals(usuario)) {
                        oldCeduladirectoreventoOfEventoList3NewEvento.getEventoList3().remove(eventoList3NewEvento);
                        oldCeduladirectoreventoOfEventoList3NewEvento = em.merge(oldCeduladirectoreventoOfEventoList3NewEvento);
                    }
                }
            }
            em.getTransaction().commit();
        } catch (Exception ex) {
            String msg = ex.getLocalizedMessage();
            if (msg == null || msg.length() == 0) {
                Integer id = usuario.getCedula();
                if (findUsuario(id) == null) {
                    throw new NonexistentEntityException("The usuario with id " + id + " no longer exists.");
                }
            }
            throw ex;
        } finally {
            if (em != null) {
                em.close();
            }
        }
    }

    public void destroy(Integer id) throws IllegalOrphanException, NonexistentEntityException {
        EntityManager em = null;
        try {
            em = getEntityManager();
            em.getTransaction().begin();
            Usuario usuario;
            try {
                usuario = em.getReference(Usuario.class, id);
                usuario.getCedula();
            } catch (EntityNotFoundException enfe) {
                throw new NonexistentEntityException("The usuario with id " + id + " no longer exists.", enfe);
            }
            List<String> illegalOrphanMessages = null;
            List<Evento> eventoList3OrphanCheck = usuario.getEventoList3();
            for (Evento eventoList3OrphanCheckEvento : eventoList3OrphanCheck) {
                if (illegalOrphanMessages == null) {
                    illegalOrphanMessages = new ArrayList<String>();
                }
                illegalOrphanMessages.add("This Usuario (" + usuario + ") cannot be destroyed since the Evento " + eventoList3OrphanCheckEvento + " in its eventoList3 field has a non-nullable ceduladirectorevento field.");
            }
            if (illegalOrphanMessages != null) {
                throw new IllegalOrphanException(illegalOrphanMessages);
            }
            List<Competencia> competenciaList = usuario.getCompetenciaList();
            for (Competencia competenciaListCompetencia : competenciaList) {
                competenciaListCompetencia.getUsuarioList().remove(usuario);
                competenciaListCompetencia = em.merge(competenciaListCompetencia);
            }
            List<Competencia> competenciaList1 = usuario.getCompetenciaList1();
            for (Competencia competenciaList1Competencia : competenciaList1) {
                competenciaList1Competencia.getUsuarioList1().remove(usuario);
                competenciaList1Competencia = em.merge(competenciaList1Competencia);
            }
            List<Evento> eventoList = usuario.getEventoList();
            for (Evento eventoListEvento : eventoList) {
                eventoListEvento.setCeduladirectorlogistica(null);
                eventoListEvento = em.merge(eventoListEvento);
            }
            List<Evento> eventoList1 = usuario.getEventoList1();
            for (Evento eventoList1Evento : eventoList1) {
                eventoList1Evento.setCeduladirectoradministrativo(null);
                eventoList1Evento = em.merge(eventoList1Evento);
            }
            List<Evento> eventoList2 = usuario.getEventoList2();
            for (Evento eventoList2Evento : eventoList2) {
                eventoList2Evento.setCeduladirectordeportivo(null);
                eventoList2Evento = em.merge(eventoList2Evento);
            }
            em.remove(usuario);
            em.getTransaction().commit();
        } finally {
            if (em != null) {
                em.close();
            }
        }
    }

    public List<Usuario> findUsuarioEntities() {
        return findUsuarioEntities(true, -1, -1);
    }

    public List<Usuario> findUsuarioEntities(int maxResults, int firstResult) {
        return findUsuarioEntities(false, maxResults, firstResult);
    }

    private List<Usuario> findUsuarioEntities(boolean all, int maxResults, int firstResult) {
        EntityManager em = getEntityManager();
        try {
            CriteriaQuery cq = em.getCriteriaBuilder().createQuery();
            cq.select(cq.from(Usuario.class));
            Query q = em.createQuery(cq);
            if (!all) {
                q.setMaxResults(maxResults);
                q.setFirstResult(firstResult);
            }
            return q.getResultList();
        } finally {
            em.close();
        }
    }

    public Usuario findUsuario(Integer id) {
        EntityManager em = getEntityManager();
        try {
            return em.find(Usuario.class, id);
        } finally {
            em.close();
        }
    }

    public int getUsuarioCount() {
        EntityManager em = getEntityManager();
        try {
            CriteriaQuery cq = em.getCriteriaBuilder().createQuery();
            Root<Usuario> rt = cq.from(Usuario.class);
            cq.select(em.getCriteriaBuilder().count(rt));
            Query q = em.createQuery(cq);
            return ((Long) q.getSingleResult()).intValue();
        } finally {
            em.close();
        }
    }
    
}
